package cn.jiangjiesheng.bootstrap.commons.response;

import cn.hutool.core.codec.Base64;
import cn.jiangjiesheng.bootstrap.commons.exception.BizzException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.util.Arrays;

/**
 * 接口异常捕获
 * <p>
 * Created by dev@jiangjiesheng.cn on 2021/8/25  <br/>
 *
 * @author jerrylau
 */
@ControllerAdvice(basePackages = {"cn.jiangjiesheng", "cn.jiangjiesheng"})
@Slf4j
public class ExceptionController extends ResponseEntityExceptionHandler {

    /**
     * 全局处理异常
     *
     * @param ex
     * @param request
     * @return
     */
    @ExceptionHandler({Exception.class})
    protected ResponseEntity<Object> handleError(RuntimeException ex, WebRequest request) {
        log.error("ExceptionController {} {}", ex.getMessage(), Arrays.toString(shortenTrace(ex.getStackTrace())));
        ex.printStackTrace();
        HttpHeaders httpHeaders = new HttpHeaders();
        return handleExceptionInternal(ex,
                ResponseWrapper.builder()
                        .result(null)
                        .message(ex.getMessage())
                        .trace(Base64.encode(Arrays.toString(shortenTrace(ex.getStackTrace()))))
                        .success(false)
                        .build(),
                httpHeaders, HttpStatus.BAD_REQUEST, request
        );
    }

    @ExceptionHandler({BizzException.class, RuntimeException.class})
    protected ResponseEntity<Object> handleBizzError(RuntimeException ex, WebRequest request) {
        log.error("ExceptionController {} {}", ex.getMessage(), Arrays.toString(shortenTrace(ex.getStackTrace())));
        ex.printStackTrace();
        HttpHeaders httpHeaders = new HttpHeaders();
        return handleExceptionInternal(ex,
                ResponseWrapper.builder()
                        .result(null)
                        .message(ex.getMessage())
                        .trace(Base64.encode(Arrays.toString(shortenTrace(ex.getStackTrace()))))
                        .success(false)
                        .build(),
                httpHeaders, HttpStatus.OK, request
        );
    }


    private StackTraceElement[] shortenTrace(StackTraceElement[] ex) {
        if (ex.length < 10) {
            return ex;
        }
        return Arrays.copyOfRange(ex, 0, 10);
    }
}
